class Song 
  attr_accessor :name, :artist, :genre, :subgenre, :tags 
  
  def initialize(list)
    @name = list[0]
    @artist = list[1]
    @genre = list[2]
    @tags = []
    [list[3].split(',').map(&:strip).each {|x| tags << x}] if list[3] != nil
    list.each_with_index do |x, i|
      if(x.include? "," and i == 2)
        genres = x.split(",").map(&:strip)
        @genre = genres[0]
        @subgenre = genres[1]    
      end
    end
    @tags << genre.downcase if not tags.include? genre
    @tags << subgenre.downcase if not tags.include? subgenre and subgenre != nil  
  end
end

class Collection 
  attr_accessor :songs_as_string, :artist_tags, :songs
  def find(criteria)
    founded_songs = []
    if(criteria == {}) 
      return songs
    end
    criteria.each do |key, value| 
      if(key == :name)
        founded_songs = find_songs_by_name(value)  
        return [] if founded_songs == []
      elsif(key == :tags)
        founded_songs = find_songs_by_tags(value)
        return [] if founded_songs == []
      elsif(key == :artist)
        founded_songs = find_songs_by_artist(value)  
        return [] if founded_songs == []
      elsif(key == :filter)
        founded_songs = find_songs_by_special_filter(value)  
        return [] if founded_songs == [] 
      end
    end
    founded_songs
  end
  
  def check_result(f_songs) 
    if f_songs == []
      return true
    end
  end
  
  def find_songs_by_special_filter(filter)
    # p filter(songs[0])
    songs.select{|x| filter.(x)}
  end
  
  def find_songs_by_tags(tagss)
    f_songs = []
    positive_tags = []
    negative_tags = []
    if not tagss.instance_of?(Array)
      if(tagss.end_with?("!"))
        negative_tags << tagss.delete('!')
      else
        positive_tags << tagss  
      end
    else
      tagss.each do |x| 
        if x.end_with?("!")
          negative_tags << x.chop
        else
          positive_tags << x 
        end
      end
    end
    if positive_tags == []
      songs.select{ |x| x.tags & negative_tags == [] }
    else
      songs.select{ |x| x.tags & positive_tags != [] and x.tags & negative_tags == [] }
    end
  end
  
  def find_songs_by_name(song_name)
    songs.select{ |x| x.name == song_name}
  end
  
  def find_songs_by_artist(artist_name)
    songs.select{ |x| x.artist == artist_name}
  end
  
  def initialize(songs_as_string, artist_tags) 
    @songs_as_string, @artist_tags = songs_as_string, artist_tags
    parse_input
    do_artist_tags
  end
  
  def parse_input()
    songs = []
    songs_as_string.lines do |x|
      songs << Song.new(remove_spaces(x, "."))
    end
    @songs = songs
  end
  
  def remove_spaces(element, split_char)
    element.split(split_char).map(&:strip)
  end
  
  def do_artist_tags() 
    artist_tags.each do |key,value|
      songs.select{|x| x.artist == key}.each do |y|
        value.each {|x| y.tags << x if y.tags & value == []} 
      end
    end
  end
  
  
end


# ["asd", "eee, e"].each_with_index do |x,i|
  # if i == 1 and x.include? ","
    # p "ok"
  # end
# end
c = Collection.new("Round Midnight. John Coltrane. Jazz\nTutu. Miles Davis. Jazz, Fusion. weird, cool\nAutumn Leaves. Bill Evans. Jazz. popular\nWaltz for Debbie. Bill Evans. Jazz\nRound Midnight. Thelonious Monk. Jazz, Bebop\nToccata e Fuga. Bach. Classical, Baroque. popular\nGoldberg Variations. Bach. Classical, Baroque", { 'John Coltrane' => %w[saxophone], 'Bach' => %w[piano polyphony] })
# c.parse_input()
p c.find tags: %w[piano jazz!]
# c.do_artist_tags()
#p c.find filter: ->(song) { song.name.start_with?('c') }
# s = Song.new("x","x","x","x","x")
# s.name = "Me myself and I"
# p s.methods
# p s.name


